import {
  Button,
  Checkbox,
  Divider,
  Dropdown,
  Flex,
  Input,
  Menu,
  Modal,
  Tabs,
  Tooltip,
  Transfer,
  Tree,
} from "antd";
import {
  CaretDownOutlined,
  CaretRightOutlined,
  CaretUpOutlined,
  DownOutlined,
} from "@ant-design/icons";

import React, { useState, useEffect, useRef } from "react";
import type { TransferDirection, TransferItem } from "antd/es/transfer";
import type { Children, Key } from "react";
import { httpClient } from "@/common/httpClient";
import { DeviceRegisterField } from "../device/devicenodes/deviceNodesFields";
import { HearderType } from "@/common/common";
import { Group } from "./groupFields";
import { title } from "process";
import modal from "antd/es/modal";

interface RegisterAddProps {}

interface TabTitleProps {
  title?: string;
  keys: any;
}
interface ChoiceItem extends TransferItem {
  title: string;
  description: string;
}

let GroupData: any, setGroupData: any;
let TreeClickState: any, setTreeClickState: any;
// let targetKeys: any, setTargetKeys: any;
// let selectedKeys: any, setSelectedKeys: any;
function convertToTreeData(originalData: any[], parentKey = "0") {
  // 如果原始数据是 undefined 或 null，或者不是数组，返回空数组
  if (!originalData || !Array.isArray(originalData)) {
    return [];
  }

  return originalData.map((item: any, index: number) => {
    // 生成当前节点的 key，格式为 "父key-当前索引"
    const currentKey = parentKey === "0" ? `${index}` : `${parentKey}-${index}`;
    // 构建基础节点
    const node: any = {
      title: item.title || `节点 ${currentKey}`, // 使用原title或默认值
      key: currentKey,
      ...item,
    };

    // 如果有子节点，递归处理[1,3](@ref)
    if (item.child && Array.isArray(item.child) && item.child.length > 0) {
      node.children = convertToTreeData(item.child, currentKey);
    }

    return node;
  });
}
// 类型示意（按你的实际类型调整）
type TreeItem = {
  key: string;
  title: string;
  child?: TreeItem[];
  // 其他业务字段...
  [key: string]: any;
};

/**
 * 将路径字符串转为索引数组，并做类型与边界校验
 */
function toIndexes(path: unknown): number[] {
  if (typeof path !== "string") return [];
  const parts = path.split("-");
  if (parts.length === 0 || (parts.length === 1 && parts[0] === "")) return [];
  const idxs: number[] = [];
  for (let i = 0; i < parts.length; i++) {
    const n = Number(parts[i]);
    if (!Number.isInteger(n) || n < 0) return []; // 非法索引直接返回空
    idxs.push(n);
  }
  return idxs;
}

/**
 * 按索引路径查找目标节点，并返回从根到目标的各级“父节点与其在该父节点中的索引”
 * 例如：[{ parent: 根, indexInParent: 0 }, { parent: 第一层节点, indexInParent: 0 }]
 */
function findPathParents(
  tree: TreeItem[],
  indexes: number[]
): { parent: TreeItem; indexInParent: number }[] {
  const pathParents: { parent: TreeItem; indexInParent: number }[] = [];
  let currentLevel: (TreeItem | TreeItem[])[] = [tree]; // 每层是一个节点或节点数组

  for (let i = 0; i < indexes.length; i++) {
    const idx = indexes[i];
    const nextLevel: (TreeItem | TreeItem[])[] = [];

    for (const nodeOrArr of currentLevel) {
      if (Array.isArray(nodeOrArr)) {
        nextLevel.push(...nodeOrArr);
      } else if (Array.isArray(nodeOrArr.child)) {
        nextLevel.push(...nodeOrArr.child);
      }
    }

    const targetParent = currentLevel[idx];
    if (
      !Array.isArray(targetParent) &&
      targetParent &&
      Array.isArray(targetParent.child)
    ) {
      pathParents.push({ parent: targetParent, indexInParent: idx });
    } else {
      return []; // 路径中断，未找到
    }

    currentLevel = nextLevel;
  }

  return pathParents;
}

const removeByPathKeys = (data: any, keys: any) => {
  const newData = JSON.parse(JSON.stringify(data));
  keys.forEach((keyPath: string) => {
    keyPath = `${keyPath}`;
    const path = keyPath.split("-").map(Number);
    let current: any = newData;
    for (let i = 0; i < path.length - 1; i++) {
      current = current[path[i]].child;
    }
    const lastIndex = path[path.length - 1];
    if (Array.isArray(current)) {
      current.splice(lastIndex, 1);
    }
  });
  return newData;
};
function addChildByPath(data: any, path: any, newChild: any) {
  // 深拷贝原数据以避免修改原数组
  const newData = JSON.parse(JSON.stringify(data));

  // 将路径字符串转换为索引数组，如 "0-0" -> [0, 0]
  const indices = path.split("-").map((index: any) => parseInt(index));

  // 递归查找目标位置
  function findTarget(arr: any, currentIndices: any) {
    if (currentIndices.length === 0) {
      return arr; // 应该不会执行到这里
    }

    const currentIndex = currentIndices[0];

    // 检查索引是否有效
    if (currentIndex < 0 || currentIndex >= arr.length) {
      throw new Error(`无效的路径索引: ${currentIndex}`);
    }

    // 如果是最后一个索引，返回目标对象
    if (currentIndices.length === 1) {
      return arr[currentIndex];
    }

    // 继续深入下一层
    const nextObj = arr[currentIndex];
    if (!nextObj.child || !Array.isArray(nextObj.child)) {
      throw new Error(`路径 ${path} 指向的对象没有 child 数组`);
    }

    return findTarget(nextObj.child, currentIndices.slice(1));
  }

  try {
    // 找到目标对象
    const target = findTarget(newData, indices);

    // 确保目标对象有 child 数组
    if (!target.child) {
      target.child = [];
    } else if (!Array.isArray(target.child)) {
      target.child = [target.child];
    }

    // 添加新的子节点
    target.child.push(newChild);

    return newData;
  } catch (error: any) {
    console.error("添加子节点时出错:", error.message);
    return data; // 出错时返回原数据
  }
}
function findObjectByPathAndRelace(
  data: any,
  path: any,
  newChild: any = undefined
) {
  // 深拷贝原数据以避免修改原数组
  const newData = JSON.parse(JSON.stringify(data));

  // 将路径字符串转换为索引数组，如 "0-0-0-1" -> [0, 0, 0, 1]
  const indices = path.split("-").map((index: any) => parseInt(index));

  // 验证路径有效性
  if (indices.length === 0) {
    return null;
  }

  try {
    let currentLevel = newData;

    // 按照路径索引逐层深入，找到目标节点的父级
    for (let i = 0; i < indices.length - 1; i++) {
      const index = indices[i];

      // 检查索引是否有效
      if (index < 0 || index >= currentLevel.length) {
        throw new Error(
          `无效的路径索引: ${index}，当前层级数组长度: ${currentLevel.length}`
        );
      }

      // 准备进入下一层
      if (
        !currentLevel[index].child ||
        !Array.isArray(currentLevel[index].child)
      ) {
        throw new Error(`路径中断: 索引 ${index} 处的对象没有 child 数组`);
      }

      currentLevel = currentLevel[index].child;
    }

    // 现在 currentLevel 是目标节点的父级数组
    const targetIndex = indices[indices.length - 1];

    // 检查目标索引是否有效
    if (targetIndex < 0 || targetIndex >= currentLevel.length) {
      throw new Error(
        `无效的目标索引: ${targetIndex}，父级数组长度: ${currentLevel.length}`
      );
    }

    // 替换目标节点
    if (newChild) {
      currentLevel[targetIndex] = { ...currentLevel[targetIndex], ...newChild };
      return newData;
    }
    return currentLevel[targetIndex];
  } catch (error) {
    console.error("查找并替换对象时出错:", error);
    return null;
  }
}

function combineTitlesByPathEnhanced(data: any, path: any, separator = "/") {
  // 验证输入数据
  if (!data || !Array.isArray(data)) {
    return "无效的输入数据";
  }

  if (!path || typeof path !== "string") {
    return "路径必须是字符串";
  }

  // 深拷贝原数据
  const newData = JSON.parse(JSON.stringify(data));
  const indices = path.split("-").map((index) => {
    const num = parseInt(index);
    if (isNaN(num)) {
      throw new Error(`路径包含非数字字符: ${index}`);
    }
    return num;
  });

  if (indices.length === 0) {
    return "路径不能为空";
  }

  try {
    const titles = [];
    let currentLevel = newData;

    for (let i = 0; i < indices.length; i++) {
      const index = indices[i];

      if (!Array.isArray(currentLevel)) {
        throw new Error(`路径中断: 索引 ${i} 处的值不是数组`);
      }

      if (index < 0 || index >= currentLevel.length) {
        throw new Error(
          `无效的路径索引: ${index}，当前层级数组长度: ${currentLevel.length}`
        );
      }

      const currentObj = currentLevel[index];

      if (!currentObj || typeof currentObj !== "object") {
        throw new Error(`路径中断: 索引 ${index} 处的值不是对象`);
      }

      titles.push(currentObj.title || `节点${i + 1}`);

      // 准备进入下一层
      if (i < indices.length - 1) {
        if (!currentObj.child) {
          currentObj.child = []; // 如果没有child，创建空数组
        } else if (!Array.isArray(currentObj.child)) {
          throw new Error(`路径中断: 索引 ${index} 处的child不是数组`);
        }
        currentLevel = currentObj.child;
      }
    }

    return titles.join(separator);
  } catch (error) {
    console.error("查找标题时出错:", error);
    return `查找失败: ${error}`;
  }
}
const TabTitle: React.FC<TabTitleProps> = ({ keys }) => {
  const menu = (
    <Menu onClick={({ key }) => handleMenuClick(key, keys)}>
      <Menu.Item key="rename">重命名</Menu.Item>
      <Menu.Item key="addChild">增加子分组</Menu.Item>
      <Menu.Item key="copy">复制</Menu.Item>
      <Menu.Item key="paste">粘贴</Menu.Item>
      <Menu.Item key="delete" danger>
        删除
      </Menu.Item>
    </Menu>
  );

  const [isEdit, setIsEdit] = useState<boolean>(false);
  const [inputValue, setInputValue] = useState<string>(
    GroupData[keys]?.title || ""
  );
  const handleMenuClick = (action: string, index: number) => {
    switch (action) {
      case "rename":
      case "addChild":
        let tempValue = GroupData[index]?.title || "";
        if (action === "addChild")
          tempValue = GroupData[index]?.title + "子分组";
        Modal.confirm({
          title: "请输入分组名称",
          content: (
            <Input
              placeholder={action === `addChild` ? tempValue : "请输入分组名称"}
              defaultValue={action === `addChild` ? "" : tempValue}
              onChange={(e) => {
                tempValue = e.target.value;
              }}
            />
          ),
          okText: "确定",
          cancelText: "取消",
          onOk() {
            if (tempValue.trim() !== "") {
              let newData = [...GroupData];
              if (action === "addChild") {
                const obj = {
                  title: tempValue,
                  child: [],
                  selectValues: [],
                };
                if (newData[index].tempKeys) {
                  //在子节点增加
                  newData = addChildByPath(
                    newData,
                    newData[index].tempKeys,
                    obj
                  );
                } else {
                  if (!newData[index].child) newData[index].child = [];
                  newData[index].child.push(obj);
                }
              } else {
                newData[index].title = tempValue;
              }
              setGroupData(newData);
            }
          },
        });
        break;

      case "delete":
        if (GroupData.length > 1) {
          Modal.confirm({
            title: "提醒",
            content: "确定要删除此分组吗？",
            okText: "确定",
            cancelText: "取消",
            onOk() {
              const newData = GroupData.filter(
                (_: any, i: number) => i !== index
              );
              setGroupData(newData);
            },
          });
        } else {
          Modal.warning({
            title: "提醒",
            content: "至少保留一个分组",
          });
        }
        break;
      // 其他操作如copy/paste可以后续实现
      default:
        break;
    }
  };

  const ChildNode: React.FC<any> = () => {
    const [treeData, setTreeData] = useState<any>([]);
    const [checkKeys, setCheckKeys] = useState<any>([]);
    useEffect(() => {
      let res = convertToTreeData(GroupData[keys].child, keys);
      let data = {
        key: keys,
        title: GroupData[keys].title,
      };
      res.unshift(data);
      setTreeData(res);
      TreeRef.current.setExpandedKeys(["0-0"]);
    }, [GroupData[keys].child]);
    const onSelect = (e: any, info: any) => {
      if (keys === info.node.key) {
        GroupData[keys].temp = "";
        GroupData[keys].tempKeys = "";
        setGroupData([...GroupData]);
      } else {
        GroupData[keys].temp = combineTitlesByPathEnhanced(
          GroupData,
          info.node.key
        );
        GroupData[keys].tempKeys = info.node.key;
        GroupData[keys].tempObj = info;
        setGroupData([...GroupData]);
      }
      TreeClickState++;
      setTreeClickState(TreeClickState);
    };
    const onCheck = (e: any) => {
      setCheckKeys([...e.checked]);
    };
    const Delete = (e: any) => {
      modal.confirm({
        title: "提醒",
        content: "确定要删除此分组吗？",
        okText: "确定",
        cancelText: "取消",
        onOk() {
          //删除GroupData 里面删除 checkKeys
          let res = removeByPathKeys(GroupData, checkKeys);
          res[keys].temp = "";
          res[keys].tempKeys = "";
          setGroupData([...res]);
        },
      });
    };
    const TreeRef = useRef<any>(null);
    return (
      <div style={{ width: "200px", height: "100%" }}>
        <Tree
          ref={TreeRef}
          showLine
          checkable
          switcherIcon={<CaretDownOutlined />}
          defaultExpandAll={true}
          defaultExpandedKeys={[GroupData[keys]?.tempKeys || 0]}
          defaultSelectedKeys={[GroupData[keys]?.tempKeys || 0]}
          blockNode={true}
          onCheck={onCheck}
          onSelect={onSelect}
          treeData={treeData}
          checkStrictly
          className="no-motion-tree"
        />
        <Divider dashed size="small" />
        <Flex justify="center">
          <Button
            size="small"
            onClick={(e) => {
              Delete(e);
            }}
          >
            确认删除
          </Button>
        </Flex>
      </div>
    );
  };
  const [isOpen, setIsOpen] = useState(false);

  return (
    <Dropdown overlay={menu} trigger={["contextMenu"]}>
      <Tooltip
        trigger="click"
        title={<ChildNode />}
        placement="bottomLeft"
        onOpenChange={(e) => {
          setIsOpen(e);
        }}
        color="#fff"
      >
        {!isOpen ? <CaretRightOutlined /> : <CaretDownOutlined />}
        <span style={{ userSelect: "none" }}>
          {GroupData[keys]?.title}
          {GroupData[keys]?.temp}
        </span>
      </Tooltip>
    </Dropdown>
  );
};
const Chioce: React.FC<any> = ({
  selectValues = [],
  keys,
  tempKeys,
  groupId,
}) => {
  const [targetKeys, setTargetKeys] = useState<Key[]>([selectValues]);
  const [selectedKeys, setSelectedKeys] = useState<Key[]>([]); //查询寄存器
  const [mockData, setMockData] = useState<ChoiceItem[]>([]);
  useEffect(() => {
    if (GroupData[keys]?.tempKeys) {
      selectValues =
        findObjectByPathAndRelace(GroupData, GroupData[keys].tempKeys)
          ?.selectValues || [];
    }
    setSelectedKeys([]);
    setTargetKeys(selectValues);
  }, [selectValues, tempKeys, TreeClickState]);

  useEffect(() => {
    if (mockData.length > 0) return;
    httpClient
      .get("admin/device_register/lists", {
        groupId: groupId,
      })
      .then((e: any) => {
        let items = e.items as DeviceRegisterField[];
        let res = items.map((v: any, k: any) => {
          return {
            key: v.id,
            title: v.registerName,
            description: "-地址:" + v.registerOffset,
          };
        });
        setMockData(res);
      });
  }, []);
  const handleChange = (nextTargetKeys: Key[]) => {
    setTargetKeys(nextTargetKeys);
    if (GroupData[keys]?.tempKeys) {
      GroupData = findObjectByPathAndRelace(
        GroupData,
        GroupData[keys]?.tempKeys,
        {
          selectValues: nextTargetKeys.filter((v) => typeof v != "object"),
        }
      );
    } else {
      GroupData[keys].selectValues = nextTargetKeys.filter(
        (v) => typeof v != "object"
      );
    }
    setGroupData(GroupData);
  };

  const handleSelectChange = (
    sourceSelectedKeys: Key[],
    targetSelectedKeys: Key[]
  ) => {
    setSelectedKeys([...sourceSelectedKeys, ...targetSelectedKeys]);
  };

  const renderFooter = () => (
    <div style={{ padding: "5px 10px", borderTop: "1px solid #f0f0f0" }}>
      <span>共 {mockData.length} 项</span>
      <span style={{ float: "right" }}>已选 {targetKeys.length} 项</span>
    </div>
  );

  return (
    <Transfer
      dataSource={mockData}
      showSearch
      titles={["可选功能", "已选功能"]}
      listStyle={{
        width: "100%",
        height: window.innerHeight - 260,
      }}
      operations={["添加", "移除"]}
      targetKeys={targetKeys as string[]} // 如果需要保持内部一致性可以适当转型
      selectedKeys={selectedKeys as string[]}
      onChange={handleChange}
      onSelectChange={handleSelectChange}
      render={(item) => `${item.title}-${item.description}`}
      footer={renderFooter}
      pagination={{ pageSize: 20 }} // 设置每页显示20条数据
    />
  );
};

const RegisterAdd: React.FC<any> = ({ groupId, keys, value }) => {
  const [loading, setLoading] = useState<boolean>(false);
  const [activeKey, setActiveKey] = useState<any>(0);
  [TreeClickState, setTreeClickState] = useState<any>(0);
  [GroupData, setGroupData] = useState<any[]>([
    {
      title: "默认分组.",
      temp: "",
      tempKeys: "",
      tempObj: undefined,
      selectValues: [],
    },
  ]);
  useEffect(() => {
    if (value && value.length > 0) {
      setGroupData(value);
    }
  }, [value]);

  useEffect(() => {
    let initData = GroupData.map((v: any, k: any) => {
      return {
        label: <TabTitle keys={k} />,
        key: k,
        children: (
          <Chioce
            selectValues={v.selectValues}
            TreeClickState={TreeClickState}
            groupId={groupId}
            keys={k}
            tempKeys={v.tempKeys}
          />
        ),
      };
    });
    setItems([...initData]);
  }, [activeKey, GroupData]);
  const [items, setItems] = useState<any[]>([]);
  const size = "large";
  const submit = async () => {
    setLoading(true);
    let requestData = GroupData.map((v: any, k: any) => {
      return {
        title: v.title,
        selectValues: v.selectValues,
        child: v.child,
      };
    });
    let res = await httpClient.post(
      "/admin/device_group/update",
      {
        [keys]: JSON.stringify(requestData),
        groupId: groupId,
      },
      {
        headers: { "Content-Type": HearderType[0] },
      }
    );
    if (res.data.data) setLoading(false);
  };
  const onEdit = (targetKey: any, action: any) => {
    if (action === "add") {
      GroupData.push({
        title: "默认名称" + (GroupData.length - 1),
        selectValues: [],
      });
      setGroupData([...GroupData]);
      setActiveKey(GroupData.length - 1);
    } else {
      Modal.confirm({
        title: "提醒",
        content: "确定要删除此分组吗？",
        okText: "确定",
        cancelText: "取消",
        onCancel() {},
        onOk() {
          setGroupData(GroupData.filter((v: any, k: any) => k !== targetKey));
        },
      });
    }
  };

  return (
    <div style={{ margin: "20px 0" }}>
      <Tabs
        type="editable-card"
        size={size}
        activeKey={activeKey}
        onChange={setActiveKey}
        onEdit={onEdit}
        items={items}
      />
      <Button
        loading={loading}
        style={{ margin: "20px 0 0 0" }}
        type="primary"
        size={size}
        onClick={submit}
      >
        保存
      </Button>
    </div>
  );
};

export default RegisterAdd;
